Skip to content

BLD: migrate build backend to meson-python and enable abi3 wheels - #556

Draft
neutrinoceros wants to merge 5 commits into
pydata:masterfrom
neutrinoceros:bld/meson
Draft

BLD: migrate build backend to meson-python and enable abi3 wheels#556
neutrinoceros wants to merge 5 commits into
pydata:masterfrom
neutrinoceros:bld/meson

Conversation

@neutrinoceros

@neutrinoceros neutrinoceros commented May 30, 2026

Copy link
Copy Markdown
Collaborator

This is based off #511
close #516
very much a work in progress.

When attempting a build with

uvx meson setup build
uvx meson compile -C build

I get 2 errors about malloc and free being undefined. Here's the first one:

bottleneck/src/reduce_template.c:819:5: error: call to undeclared library function 'malloc' with type 'void *(unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  819 |     BUFFER_NEW(float64, LENGTH)
      |     ^
bottleneck/src/reduce_template.c:802:31: note: expanded from macro 'BUFFER_NEW'
  802 |         npy_##dtype *buffer = malloc(length * sizeof(npy_##dtype));
      |                               ^
bottleneck/src/reduce_template.c:819:5: note: include the header <stdlib.h> or explicitly provide a declaration for 'malloc'

I don't understand how this happens, #include <stdlib.h> is already present in bottleneck/src/reduce_template.c.

If I run uv build instead, I get

../meson.build:25:3: ERROR: File bottleneck/src/reduce.c does not exist.

so clearly I must be doing something wrong, but I'm not too surprised because this is the first time I attempt to hook python scripts into a meson build.

@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 3 times, most recently from 679039b to fd49952 Compare May 31, 2026 08:25
@neutrinoceros

neutrinoceros commented May 31, 2026

Copy link
Copy Markdown
Collaborator Author

I reached a somewhat functional state where at least some jobs are passing.
What's broken:

  • docs: many references to setup.py (critical)
  • mnt: Makefile and bn_setup.sh should be either removed or updated (tbd)
  • warnings-as-errors in tests (very important)
  • dynamic config from setuptools (possibly not needed, but I need to understand what I'm giving up)
  • dynamic version number (nice to have, but I'm not personally motivated to preserve this)

@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

looks like this is what's failing windows-arm64 jobs: astral-sh/uv#12906

@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

got a bit further using the workaround described in the issue I just linked. Now meson correctly detects a native Python interpreter, but then hit

C:\a\_temp\uv-python-dir\cpython-3.11.15-windows-aarch64-none\python311.dll:
      file not recognized: file format not recognized

which I don't understand yet

@rgommers rgommers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a quick looks; this looks like a good start to me.

Comment thread meson.build Outdated
Comment thread meson.build Outdated
'nonreduce_axis',
[
bn_config_h,
custom_target(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you define a generator, this can be a one-liner per file, same as in for example:

https://github.com/scipy/scipy/blob/20c4b5e75727ae1d3dc19a2bb8c65c43f1366592/scipy/sparse/meson.build#L7-L8

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a generator is how I initially tried to write this but I struggled to define a template for the output filename, because it's obtained by subtraction rather than addition.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could rename the source files? They're not valid C code, so .c.in or .c.template seems more accurate anyway

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was thinking doing just that as a cleanup step after I got CI stable again. Though I prefer extensions like .template.c, as it allows syntax highlighting to sort-of work instead of not at all.

@neutrinoceros neutrinoceros May 31, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually went for it tonight because I had limited bandwidth and this didn't require much. I ended up using your suggestion (.c.template) because I couldn't work out how to implement .template.c using available substitutions .

Comment thread meson.build Outdated
@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 5 times, most recently from 11ff03d to fc3f675 Compare June 1, 2026 08:16
@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

I'm hesitant to just drop windows-arm64 as a normal CI target. It works in the context of cibw but I'm struggling to set it up using actions/setup-python and/or astral-sh/setup-uv.

@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 8 times, most recently from 7f54ef5 to f995b9d Compare June 2, 2026 07:35
@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

I got lost as I tried to get everything working at the same time. I've disabled limited-api builds for now because I found it hard to setup correctly with 3.14t also being a target. I'm also disabling failing targets as I go right now, with the goal to reveal the subset that does work already, before I tackle failures one by one again.

@rgommers

rgommers commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

Oh wait, the wheel build issue does ring a bell: the problem here is that we're building all Windows wheels in a single job (which none of the other projects I work on do; it leads to issues like this one), and CPython didn't fix a free-threading header issue - that's why the 3.11 to 3.14 builds work and 3.14t chokes. From https://py-free-threading.github.io/installing-cpython/:

"Due to limitations of the Windows Python.org installer, using free-threaded Python installed from the Python.org installer may lead to trouble. In particular, if you install both a free-threaded and gil-enabled build of Python 3.13+ using the Python.org installer, both installs will share a site-packages folder. This can very quickly lead to broken environments if packages for both versions are simultaneously installed."

Let me figure out if there's an easy workaround.

@rgommers

Copy link
Copy Markdown
Collaborator

@neutrinoceros the problem is config-settings = { build-dir = "build" I think: that reuses the exact same build directory across all builds on win-arm64. That won't work in this case, because numpy is now installed in a different location. I think it's a recipe for problems. Separate jobs would fix it, or separate build directories. Reusing build dirs between jobs never seems healthy to me.

@rgommers

Copy link
Copy Markdown
Collaborator

Those fixups don't look right. I thought about it some more, and reusing a build directory is just not a valid thing to do between two fresh builds with different dependencies.

build-dir = "build" should be deleted from pyproject.toml. That way meson-python will simply create a fresh build dir, avoiding the problem. I think restructuring the jobs to have a single build per job is a bit more work, but better - it's a lot easier to understand, and safer.

I'll note that setuptools happens to work in this case, because within the build dir it does namespacing like so:

build/
    cp313-win_arm64/
    cp314-win_arm64/
    cp314t-win_arm64/

that's special-casing the interpreter, which makes it work - but in general it's also susceptible to changes between builds that aren't special-cased (e.g., a change to a compiler, codegen, etc.).

Meson, as a general-purpose build system, treats Python as any other dependency and not one with special-casing for how build caching and meson setup --reconfigure work.

@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 2 times, most recently from 0c4ff54 to bdd5f3f Compare September 13, 2026 09:01
@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

I must not be understanding where the meson executable is even found. Is it included in the docker image ?
No, meson is a dependency of meson-python.

Let me clarify: the issue I'm seeing is that despite having meson==1.11.2 locked, uv is still somehow installing 1.12.0 in CI. I initially assume uv would respect my constraint, which meant meson 1.12.0 had to come from somewhere else, but having turned on uv's debug log I can see that the problem is really there.

@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

Ah ! I think that's just because the build isolation intentionally ignores runtime constraints. Promoting the constraint to an actual build-time requirement should do the trick.

@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 3 times, most recently from 76deb7d to 9e51d2d Compare September 13, 2026 10:06
@neutrinoceros

neutrinoceros commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator Author

Okay wheels are working now.
The remaining errors are all on regular windows CI, and relate to interpreter selection in at least 3 different ways:

  1. cp315 + x64combos are either unsupported by actions/setup-python, or misconfigured
The version '3.15' with architecture 'x64' was not found for Windows 2022.
  1. build-time failures for x86
Need python for x86_64, but found x86
        Run-time dependency python found: NO  (tried pkgconfig and sysconfig)
  
        ..\meson.build:43:3: ERROR: Python dependency not found
  1. A linker error on windows arm64
2026-09-13T10:08:26.4415431Z       C:\hostedtoolcache\windows\Python\3.11.9\arm64\python311.dll: file not
2026-09-13T10:08:26.4415776Z       recognized: file format not recognized
2026-09-13T10:08:26.4416050Z       collect2.exe: error: ld returned 1 exit status

I think 1 and 2 are relatively simple to fix. I'll give it a try now.

@neutrinoceros

neutrinoceros commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator Author
  1. I got x64 jobs to work by downgrading Python to 3.14
  2. I don't really understand the difference between x86 and x86_64, any chance this is a shortcoming from meson itself ?
  3. I still have no idea how to fix the linker error on arm64

@rgommers

Copy link
Copy Markdown
Collaborator

2. I don't really understand the difference between x86 and x86_64, any chance this is a shortcoming from meson itself ?

x86 is a 32-bit interpreter. Need python for x86_64, but found x86 is the standard issue where we need/use the bus1/cabuild action to activate 32-bit MSVC, except in reverse - so the job is using that action when it shouldn't.

I still have no idea how to fix the linker error on arm64

It's picking up MinGW:

        C compiler for the host machine: cc (gcc 14.2.0 "cc
        (x86_64-posix-seh-rev2, Built by MinGW-Builds project) 14.2.0")

Pass --vsenv to the build to force MSVC, like in the wheel build jobs.

  1. cp315 + x64combos are either unsupported by actions/setup-python, or misconfigured

Needs a pre-release set to true probably?

@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

Thanks !

  • arm64 is go
  • windows CI is back to Python 3.15

x86 is a 32-bit interpreter. Need python for x86_64, but found x86 is the standard issue where we need/use the bus1/cabuild action to activate 32-bit MSVC, except in reverse - so the job is using that action when it shouldn't.

But bus1/cabuild isn't used at all in regular CI, it's just there for cibw, so I'm still confused. On the off chance that you got it mixed up, I tried adding the action to regular CI, and the error message is different, but it's still failing.

Comment thread .github/workflows/ci.yml
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this duplicates a Python install from ./.github/bottleneck-action with setup-uv.

@rgommers

Copy link
Copy Markdown
Collaborator

Try inserting this in test-windows (copied from numpy):

      - name: pkg-config
        run: |
          python -m pip install pkgconf==2.5.1.post1

It's going wrong in the Python detection on x86-64, and the CI log has this warning:

 WARNING: Found pkg-config 'C:\\Strawberry\\perl\\bin\\pkg-config.BAT'

The windows-latest image has a completely broken pkg-config on the PATH and for some reason that I don't know about, GitHub doesn't get that fixed.

@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

Interesting. The errors we get now look furiously like the ones we saw with bus1/cabuild

@neutrinoceros
neutrinoceros force-pushed the bld/meson branch 3 times, most recently from 97c1c0c to 7197ab3 Compare September 13, 2026 15:52
@neutrinoceros

Copy link
Copy Markdown
Collaborator Author

CI is almost there, though I don't think I'll have time to work on this in the next 2 weeks. If anyone wants to pick it up in the mean time be my guest.

@rgommers

Copy link
Copy Markdown
Collaborator

Thanks for the push. I'll try to find some time to figure out why this wasn't easier. It really should be; there might be some weird cibuildwheel/meson/abi3 interaction that made this more complicated than it is for numpy and scipy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement packaging Issues related to installing or building bottleneck

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BLD: adopting the meson build backend

2 participants